package com.itheima.aop;

import com.itheima.anno.Log;
import com.itheima.mapper.OperateLogMapper;
import com.itheima.pojo.OperateLog;
import com.itheima.util.CurrentHolder;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.Arrays;

@Aspect//切面类
@Component//组件
public class OperationLogAspect {

    //这段代码是一个基于AOP的日志记录切面，用于拦截Controller层方法执行前后，记录操作日志。主要功能包括：
    //
    //1. 在方法执行前记录开始时间；
    //2. 执行目标方法；
    //3. 记录结束时间并计算耗时；
    //4. 将方法信息、用户ID、执行时间等封装为日志对象；
    //5. 通过MyBatis插入到数据库。
    //
    //同时提供了获取当前用户ID的方法，支持空值处理。
    @Autowired
    private OperateLogMapper operateLogMapper;

    // 环绕通知
    @Around("@annotation(log)")
    @Pointcut("execution(* com.itheima.controller..*(..)) && !execution(* com.itheima.controller.LoginController.login(..))")
    public Object around(ProceedingJoinPoint joinPoint, Log log) throws Throwable {
        // 记录开始时间
        long startTime = System.currentTimeMillis();
        // 执行方法
        Object result = joinPoint.proceed();
        // 当前时间
        long endTime = System.currentTimeMillis();
        // 耗时
        long costTime = endTime - startTime;

        // 构建日志对象
        OperateLog operateLog = new OperateLog();
        operateLog.setOperateEmpId(getCurrentUserId()); // 需要实现 getCurrentUserId 方法
        operateLog.setOperateTime(LocalDateTime.now());
        operateLog.setClassName(joinPoint.getTarget().getClass().getName());
        operateLog.setMethodName(joinPoint.getSignature().getName());
        operateLog.setMethodParams(Arrays.toString(joinPoint.getArgs()));
        operateLog.setReturnValue(result.toString());
        operateLog.setCostTime(costTime);

        // 插入日志
        operateLogMapper.insert(operateLog);
        return result;
    }

    // 示例方法，获取当前用户ID
    private Integer getCurrentUserId() {
        // 添加null检查
        Integer userId = CurrentHolder.getCurrentId();
        if (userId == null) {
            // 可以返回默认值，如0表示未登录用户
            // 或者根据业务需求抛出更明确的异常
            return 0;
        }
        return userId;
    }
}